typedef enum {
SHELL_APP_INFO_TYPE_ENTRY,
- SHELL_APP_INFO_TYPE_DESKTOP_FILE
+ SHELL_APP_INFO_TYPE_DESKTOP_FILE,
+ SHELL_APP_INFO_TYPE_WINDOW
} ShellAppInfoType;
struct _ShellAppInfo {
GKeyFile *keyfile;
char *keyfile_path;
+
+ MetaWindow *window;
+ char *window_id;
};
ShellAppInfo*
case SHELL_APP_INFO_TYPE_DESKTOP_FILE:
g_key_file_free (info->keyfile);
g_free (info->keyfile_path);
+ case SHELL_APP_INFO_TYPE_WINDOW:
+ g_object_unref (info->window);
+ g_free (info->window_id);
break;
}
g_slice_free (ShellAppInfo, info);
return info;
}
+static ShellAppInfo *
+shell_app_info_new_from_window (MetaWindow *window)
+{
+ ShellAppInfo *info;
+
+ info = g_slice_alloc (sizeof (ShellAppInfo));
+ info->type = SHELL_APP_INFO_TYPE_WINDOW;
+ info->refcount = 1;
+ info->window = g_object_ref (window);
+ /* For windows, its id is simply its pointer address as a string.
+ * There are various other alternatives, but the address is unique
+ * and unchanging, which is pretty much the best we can do.
+ */
+ info->window_id = g_strdup_printf ("window:%p", window);
+ return info;
+}
+
static ShellAppInfo *
shell_app_info_new_from_keyfile_take_ownership (GKeyFile *keyfile,
const char *path)
g_slist_free (tmp);
}
-
-
void
shell_app_system_add_favorite (ShellAppSystem *system, const char *id)
{
return appinfo;
}
+/**
+ * shell_app_system_create_from_window:
+ *
+ * In the case where we can't otherwise determine an application
+ * associated with a window, this function can create a "fake"
+ * application just backed by information from the window itself.
+ *
+ * Return value: (transfer full): A new #ShellAppInfo
+ */
+ShellAppInfo *
+shell_app_system_create_from_window (ShellAppSystem *system, MetaWindow *window)
+{
+ return shell_app_info_new_from_window (window);
+}
+
/**
* shell_app_system_lookup_heuristic_basename:
* @name: Probable application identifier
return gmenu_tree_entry_get_desktop_file_id ((GMenuTreeEntry*)info->entry);
case SHELL_APP_INFO_TYPE_DESKTOP_FILE:
return info->keyfile_path;
+ case SHELL_APP_INFO_TYPE_WINDOW:
+ return info->window_id;
}
g_assert_not_reached ();
return NULL;
return g_strdup (gmenu_tree_entry_get_name ((GMenuTreeEntry*)info->entry));
case SHELL_APP_INFO_TYPE_DESKTOP_FILE:
return g_key_file_get_locale_string (info->keyfile, DESKTOP_ENTRY_GROUP, "Name", NULL, NULL);
+ case SHELL_APP_INFO_TYPE_WINDOW:
+ {
+ char *title;
+ g_object_get (info->window, "title", &title, NULL);
+ return title;
+ }
}
g_assert_not_reached ();
return NULL;
return g_strdup (gmenu_tree_entry_get_comment ((GMenuTreeEntry*)info->entry));
case SHELL_APP_INFO_TYPE_DESKTOP_FILE:
return g_key_file_get_locale_string (info->keyfile, DESKTOP_ENTRY_GROUP, "Comment", NULL, NULL);
+ case SHELL_APP_INFO_TYPE_WINDOW:
+ return NULL;
}
g_assert_not_reached ();
return NULL;
return g_strdup (gmenu_tree_entry_get_exec ((GMenuTreeEntry*)info->entry));
case SHELL_APP_INFO_TYPE_DESKTOP_FILE:
return g_key_file_get_string (info->keyfile, DESKTOP_ENTRY_GROUP, "Exec", NULL);
+ case SHELL_APP_INFO_TYPE_WINDOW:
+ return NULL;
}
g_assert_not_reached ();
return NULL;
case SHELL_APP_INFO_TYPE_ENTRY:
return g_strdup (gmenu_tree_entry_get_desktop_file_path ((GMenuTreeEntry*)info->entry));
case SHELL_APP_INFO_TYPE_DESKTOP_FILE:
- return g_strdup (info->keyfile_path);;
+ return g_strdup (info->keyfile_path);
+ case SHELL_APP_INFO_TYPE_WINDOW:
+ return NULL;
}
g_assert_not_reached ();
return NULL;
}
-GIcon *
-shell_app_info_get_icon (ShellAppInfo *info)
+static GIcon *
+themed_icon_from_name (const char *iconname)
{
- char *iconname = NULL;
GIcon *icon;
- /* This code adapted from gdesktopappinfo.c
- * Copyright (C) 2006-2007 Red Hat, Inc.
- * Copyright © 2007 Ryan Lortie
- * LGPL
- */
-
- switch (info->type)
- {
- case SHELL_APP_INFO_TYPE_ENTRY:
- iconname = g_strdup (gmenu_tree_entry_get_icon ((GMenuTreeEntry*)info->entry));
- break;
- case SHELL_APP_INFO_TYPE_DESKTOP_FILE:
- iconname = g_key_file_get_locale_string (info->keyfile, DESKTOP_ENTRY_GROUP, "Icon", NULL, NULL);
- break;
- }
-
if (!iconname)
- return NULL;
+ return NULL;
if (g_path_is_absolute (iconname))
{
GFile *file;
-
file = g_file_new_for_path (iconname);
icon = G_ICON (g_file_icon_new (file));
g_object_unref (file);
- }
+ }
else
{
char *tmp_name, *p;
{
*p = 0;
}
-
icon = g_themed_icon_new (tmp_name);
g_free (tmp_name);
}
- g_free (iconname);
return icon;
}
+static GIcon *
+shell_app_info_get_icon (ShellAppInfo *info)
+{
+ char *iconname = NULL;
+ GIcon *icon;
+
+ /* This code adapted from gdesktopappinfo.c
+ * Copyright (C) 2006-2007 Red Hat, Inc.
+ * Copyright © 2007 Ryan Lortie
+ * LGPL
+ */
+
+ switch (info->type)
+ {
+ case SHELL_APP_INFO_TYPE_ENTRY:
+ return themed_icon_from_name (gmenu_tree_entry_get_icon ((GMenuTreeEntry*)info->entry));
+ case SHELL_APP_INFO_TYPE_DESKTOP_FILE:
+ iconname = g_key_file_get_locale_string (info->keyfile, DESKTOP_ENTRY_GROUP, "Icon", NULL, NULL);
+ icon = themed_icon_from_name (iconname);
+ g_free (iconname);
+ return icon;
+ break;
+ case SHELL_APP_INFO_TYPE_WINDOW:
+ return NULL;
+ }
+ g_assert_not_reached ();
+ return NULL;
+}
+
GSList *
shell_app_info_get_categories (ShellAppInfo *info)
{
case SHELL_APP_INFO_TYPE_ENTRY:
return gmenu_tree_entry_get_is_nodisplay ((GMenuTreeEntry*)info->entry);
case SHELL_APP_INFO_TYPE_DESKTOP_FILE:
+ case SHELL_APP_INFO_TYPE_WINDOW:
return FALSE;
}
g_assert_not_reached ();
return TRUE;
}
+/**
+ * shell_app_info_is_transient:
+ *
+ * A "transient" application is one which represents
+ * just an open window, i.e. we don't know how to launch it
+ * again.
+ */
+gboolean
+shell_app_info_is_transient (ShellAppInfo *info)
+{
+ return info->type == SHELL_APP_INFO_TYPE_WINDOW;
+}
+
/**
* shell_app_info_create_icon_texture:
*
GIcon *icon;
ClutterActor *ret;
+ if (info->type == SHELL_APP_INFO_TYPE_WINDOW)
+ {
+ return shell_texture_cache_bind_pixbuf_property (shell_texture_cache_get_default (),
+ G_OBJECT (info->window),
+ "icon");
+ }
+
icon = shell_app_info_get_icon (info);
if (!icon)
{
if (startup_id)
*startup_id = NULL;
+ if (info->type == SHELL_APP_INFO_TYPE_WINDOW)
+ {
+ /* We can't pass URIs into a window; shouldn't hit this
+ * code path. If we do, fix the caller to disallow it.
+ */
+ g_return_val_if_fail (uris == NULL, TRUE);
+
+ meta_window_activate (info->window, timestamp);
+ return TRUE;
+ }
+
filename = shell_app_info_get_desktop_file_path (info);
gapp = g_desktop_app_info_new_from_filename (filename);
g_free (filename);